/*
 * Copyright (c) 2006-2019, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author         Notes
 * 2019-08-15    xiangxistu      the first version
 * 2019-09-26    xiangxistu      add ppp_device_attach and ppp_device_detach
 */

#include <rtconfig.h>

#ifdef USING_PPP_DEVICE

#include <rtthread.h>
#include "ppp_device.h"
#include "ppp_utils.h"

#define DBG_TAG    "ppp.utils"

#ifdef PPP_DEVICE_DEBUG
#define DBG_LVL   DBG_LOG
#else
#define DBG_LVL   DBG_LOG
#endif

#include <rtdbg.h>

/**
 * Create response object.
 *
 * @param max_size the maximum response buffer size
 * @param line_num the number of setting response lines
 *         = 0: the response data will auto return when received 'OK' or 'ERROR'
 *        != 0: the response data will return when received setting lines number data
 * @param timeout the maximum response ticks
 *
 * @return != RT_NULL: response object
 *          = RT_NULL: no memory
 */
ppp_at_resp *ppp_at_resp_create(int line_num, int max_size, rt_tick_t timeout)
{
    int result;
    ppp_at_resp *resp = RT_NULL;

    resp = (ppp_at_resp *) rt_calloc(1, sizeof(ppp_at_resp));
    if (resp == RT_NULL)
    {
        LOG_E("ppp create resp object failed! No memory for resp object!");
        return RT_NULL;
    }

    resp->buffer = (char *) rt_calloc(1, max_size);
    if (resp->buffer == RT_NULL)
    {
        LOG_E("PPP create response object failed! No memory for response buffer!");
        rt_free(resp);
        return RT_NULL;
    }

    resp->max_size = max_size;
    resp->line_num = line_num;
    resp->timeout = timeout;

    return resp;
}

/**
 * Delete and free response object.
 *
 * @param resp response object
 */
void ppp_at_resp_delete(ppp_at_resp *resp)
{
    if (resp && resp->buffer)
    {
        rt_free(resp->buffer);
    }

    if (resp)
    {
        rt_free(resp);
        resp = RT_NULL;
    }
}

/* if you want connect network again, you can use this function to create a new ppp link */
int ppp_device_start(void)
{
    rt_device_t device = RT_NULL;
    device = rt_device_find(PPP_DEVICE_NAME);
    if(device == RT_NULL)
    {
        LOG_E("Can't find device (%s).", PPP_DEVICE_NAME);
        return -RT_ERROR;
    }
    if(ppp_device_attach((struct ppp_device *)device, PPP_CLIENT_NAME, RT_NULL) != RT_EOK)
    {
        LOG_E("ppp_device_attach execute failed.");
        return -RT_ERROR;
    }
    
    LOG_I("ppp device(%s) initialize success.", PPP_DEVICE_NAME);
    return RT_EOK;
}
#ifndef PKG_USING_CMUX
INIT_APP_EXPORT(ppp_device_start);
#endif
MSH_CMD_EXPORT_ALIAS(ppp_device_start, ppp_start, a sample of ppp device  for dailing to network);

/* close ppp link ,turn off modem form network */
int ppp_device_stop(void)
{
    rt_device_t device = RT_NULL;
    device = rt_device_find(PPP_DEVICE_NAME);
    if(device == RT_NULL)
    {
        LOG_E("Can't find device (%s).", PPP_DEVICE_NAME);
        return -RT_ERROR;
    }
    if(ppp_device_detach((struct ppp_device *)device) != RT_EOK)
    {
        LOG_E("ppp_device_detach execute failed.");
        return -RT_ERROR;
    }
    return RT_EOK;
}
MSH_CMD_EXPORT_ALIAS(ppp_device_stop, ppp_stop, a sample of ppp device for turning off network);

#ifdef PPP_DEVICE_DEBUG_DROP
static int ppp_drop(void)
{
    rt_device_t device = RT_NULL;
    struct ppp_device *ppp_device;
    device = rt_device_find(PPP_DEVICE_NAME);
    if(device == RT_NULL)
    {
        LOG_E("Can't find device (%s).", PPP_DEVICE_NAME);
        return -RT_ERROR;
    }
    ppp_device = (struct ppp_device*)device;
    LOG_I("%ld", (unsigned long)(ppp_device->dropcnt + ppp_device->droppos));
    return RT_EOK;
 }

MSH_CMD_EXPORT_ALIAS(ppp_drop, ppp_drop, show drop statistics);
#endif

#endif
